﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Diagnostics;
using System.Drawing;
using Buccaneer.Types;
using PluginInterface;
using Buccontrols;

namespace Buccaneer
{
    public partial class MainProgram
    {
        public static PluginServices Plugins;
        public static Thread ConsoleThread;
        public static AvailablePlugin selectedPlugin;
        public static Daddy MainForm;

        [STAThread]
        static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(true);

            #region Setup Console

            Console.BufferWidth = 200;
            TextWriterTraceListener myWriter = new TextWriterTraceListener(System.Console.Out);
            Debug.Listeners.Add(myWriter);

            #endregion

            Console.WriteLine("Starting Buccaneer...");

            #region Register actions

            MainProgram.Plugins = new PluginServices();
            MainProgram.Plugins.RegisterAction("exit", new ActionFunction(ExitApplication));
            MainProgram.Plugins.RegisterAction("navigate", new ActionFunction(Navigate));
            MainProgram.Plugins.RegisterAction("navigateback", new ActionFunction(NavigateBack));
            MainProgram.Plugins.RegisterAction("navigateforward", new ActionFunction(NavigateForward));
            MainProgram.Plugins.RegisterAction("navigatedown", new ActionFunction(NavigateDown));
            MainProgram.Plugins.RegisterAction("navigateup", new ActionFunction(NavigateUp));
            MainProgram.Plugins.RegisterAction("loadrescimg", new ActionFunction(LoadRescImage));
            MainProgram.Plugins.RegisterAction("showrescimg", new ActionFunction(ShowRescImage));
            MainProgram.Plugins.RegisterAction("help", new ActionFunction(ShowHelp));
            MainProgram.Plugins.RegisterAction("addform", new ActionFunction(AddForm));
            MainProgram.Plugins.RegisterAction("addformt", new ActionFunction(AddFormThreadSafe));
            MainProgram.Plugins.RegisterAction("loadplugin", new ActionFunction(LoadPlugin));
            
            #endregion

            #region 1: Load options

            Options.Initialize();
            Options.Font = new Font(FontFamily.GenericSansSerif, 12.0f);
            Options.LayoutFolder = Environment.CurrentDirectory + @"\Layout";
            Options.PluginsFolder = Environment.CurrentDirectory + @"\Plugins";
            Options.WriteComment(Options.LayoutFolder);
            Options.StartupPluginName = "FileBrowser";
            Options.ShownCommentTypes.AddRange(new string[] { "(i) ", "(!) ", "(?) ", "(x) ", "(A) ", " -  ", "Load" });
            Options.WriteComment("Loaded Options...");

            #endregion

            #region 2: Load images/layout

            Options.LoadImageDirectory(Options.LayoutFolder);
            Plugins.Act("loadrescimg", new string[] 
            { 
                "formBack", 
                Options.LayoutFolder + "back.png" 
            });
            Plugins.Act("loadrescimg", new string[] 
            { 
                "addressBar", 
                Options.LayoutFolder + "addressBar.png" 
            });
            Plugins.Act("loadrescimg", new string[] 
            { 
                "addressBarLeft", 
                Options.LayoutFolder + "addressBarBegin.png" 
            });
            Plugins.Act("loadrescimg", new string[] 
            { 
                "addressBarRight", 
                Options.LayoutFolder + "addressBarEnd.png" 
            });
            Options.WriteComment("Loaded Layout...");

            #endregion

            #region 3: Create form

            Global.EnableCommandTyping();

            MainForm = new Daddy(MainProgram.Plugins);
            Plugins.Act("addformt", null);

            Options.WriteComment("Loaded Form...");

            #endregion

            #region 4: Load Plugins

            if (Global.LoadPlugins()) Options.WriteComment("Loaded Plugins...");
            else Options.WriteComment("No Plugins found!");
            selectedPlugin = Plugins.AvailablePlugins.Find(Options.StartupPluginName);
            if (selectedPlugin != null)
            {
                selectedPlugin.Instance.MainInterfaceParent = MainProgram.MainForm;
                selectedPlugin.Instance.MainInterface.Show();
                MainProgram.Plugins.SwitchToPlugin(selectedPlugin);
            }

            #endregion

            #region 5: Run Application

            Options.WriteComment("Running Application..."); Options.WriteComment("");
            Application.Run(MainForm);
            Environment.Exit(0);

            #endregion
        }

        #region ActionFunctions

        public static void ExitApplication(string[] args)
        {
            if (args == null)
            {
                Options.WriteComment("(i) Please parse 1 parameter, namely:");
                Options.WriteComment(" -  the reason for the application to exit");
                return;
            }
            Application.Exit();
        }

        public static void Navigate(string[] args)
        {
            if (args == null || args[0] == "")
            {
                Options.WriteComment("(!) Please parse 1 parameter, namely:");
                Options.WriteComment(" -  the path to navigate to");
                return;
            }
            selectedPlugin.Instance.Navigate(args[0]);
        }

        public static void NavigateUp(string[] args)
        {
            if (args == null) return;
            selectedPlugin.Instance.NavigateUp();
        }

        public static void NavigateDown(string[] args)
        {
            if (args == null) return;
            selectedPlugin.Instance.NavigateDown();
        }

        public static void NavigateForward(string[] args)
        {
            if (args == null) return;
            selectedPlugin.Instance.NavigateForward();
        }

        public static void NavigateBack(string[] args)
        {
            if (args == null || args[0] == "") return;
            selectedPlugin.Instance.NavigateBack();
        }

        public static void LoadRescImage(string[] args)
        {
            if (args == null || args.Length < 2 || args[1] == "")
            {
                Options.WriteComment("(!) Please parse 2 parameters, namely:");
                Options.WriteComment(" -  name of the image to be used later on");
                Options.WriteComment(" -  path of the file to be loaded");
                return;
            }
            Options.LoadImage(args[0], args[1]);
        }

        public static void ShowRescImage(string[] args)
        {
            if (args == null || args[0] == "")
            {
                Options.WriteComment("(!) Please parse 1 parameter, namely:");
                Options.WriteComment(" -  name of the image resource");
                return;
            }
            Image img = (Image)Options.GetResource(args[0]);
            Form frm = new Form();
            frm.Size = img.Size;
            frm.BackgroundImage = img;
            frm.ShowDialog();
        }

        public static void ShowHelp(string[] args)
        {
            if (args == null || args[0] == "")
                Plugins.GetActionHelp();
            else
                Plugins.Act(args[0], null);
        }

        public static void AddForm(string[] args)
        {
            PluginForm frm = new PluginForm();
            frm.MdiParent = MainProgram.MainForm;
            frm.Name = "PluginForm" + MainProgram.MainForm.MdiChildren.Length.ToString();
            frm.Show();
        }

        public static void AddFormThreadSafe(string[] args)
        {
            MainProgram.MainForm.ActRequest("addform", args);
        }

        public static void LoadPlugin(string[] args)
        {
            if (args == null || args[0] == "")
            {
                Options.WriteComment("(!) Please parse 1 parameter, namely:");
                Options.WriteComment(" -  the full name of the plugin");
                return;
            }
            if (Global.LoadPlugins()) Options.WriteComment("Loaded Plugins...");
            else Options.WriteComment("No Plugins found!");
            selectedPlugin = Plugins.AvailablePlugins.Find(Options.StartupPluginName);
            if (selectedPlugin != null)
            {
                selectedPlugin.Instance.MainInterfaceParent = MainProgram.MainForm;
                selectedPlugin.Instance.MainInterface.Show();
                MainProgram.Plugins.SwitchToPlugin(selectedPlugin);
            }
        }

        #endregion
    }
}